package com.micro.platform.oauth.controller.apis;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONValidator;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.micro.platform.starter.domain.ApiMateInfo;
import com.micro.platform.starter.domain.Result;
import com.micro.platform.starter.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

@Api(tags = "Api信息")
@RestController
@RequestMapping("/apis")
public class ApisController {

    private static final String APIS_ENDPOINT_PATH = "/actuator/api";

    private RestTemplate restTemplate = new RestTemplate();

    @Autowired
    private LoadBalancerClient loadBalancer;

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Autowired
    private NacosServiceManager nacosServiceManager;

    @ApiOperation("聚合列表")
    @PostMapping("/together-list")
    public Result<List<ApiMateInfo>> list(){
        ArrayList<ApiMateInfo> apis = new ArrayList<>();
        List<String> serverIds = getALlServerIds();
        for (String serverId : serverIds) {
            URI uri = buidlUrl(serverId);
            apis.addAll(getApis(uri));
        }
        return Result.ok(apis);
    }

    private List<ApiMateInfo> getApis(URI uri) {
        ArrayList<ApiMateInfo> apis = new ArrayList<>();
        String forObject = restTemplate.getForObject(uri.toString(), String.class);
        if(StringUtils.isNotEmpty(forObject) && JSONValidator.from(forObject).validate()){
            List<ApiMateInfo> apiMateInfos = JSON.parseArray(forObject, ApiMateInfo.class);
            if(CollectionUtils.isNotEmpty(apiMateInfos)){
                apis.addAll(apiMateInfos);
            }
        }
        return apis;
    }

    private URI buidlUrl(String serverId) {
        ServiceInstance serviceInstance = loadBalancer.choose(serverId);
        String contextPath = serviceInstance.getMetadata().get("contextPath");
        if(StringUtils.isEmpty(contextPath) || "/".equals(contextPath)){
            contextPath = "";
        }
        URI uri = loadBalancer.reconstructURI(serviceInstance, URI.create(contextPath + APIS_ENDPOINT_PATH));
        return uri;
    }

    public List<String> getALlServerIds(){
        List<String> serverIds = new ArrayList<>();
        String group = this.nacosDiscoveryProperties.getGroup();
        NamingService namingService = nacosServiceManager.getNamingService(nacosDiscoveryProperties.getNacosProperties());
        try {
            ListView<String> servicesOfServer = namingService.getServicesOfServer(0, 100000, group);
            serverIds.addAll(servicesOfServer.getData());
        } catch (NacosException e) {
            e.printStackTrace();
        }
        return serverIds;
    }
}
